Skip to content

[improvement](hive) Batch Hive metastore partition access - #67186

Open
CalvinKirs wants to merge 29 commits into
apache:masterfrom
CalvinKirs:batch_interface
Open

[improvement](hive) Batch Hive metastore partition access#67186
CalvinKirs wants to merge 29 commits into
apache:masterfrom
CalvinKirs:batch_interface

Conversation

@CalvinKirs

@CalvinKirs CalvinKirs commented Aug 27, 2026

Copy link
Copy Markdown
Member

What problem does this PR solve?

Issue Number: None

Related PR: None

Problem Summary:

Hive tables with very large partition counts could either issue one HMS partition-object RPC per partition on legacy caller paths or send every partition name in one unbounded getPartitionsByNames request. The first form creates excessive serial RPC latency; the second risks Thrift/HMS message limits and large temporary allocations.

This PR narrows the change to the shared HMS partition-object boundary. Callers continue to submit one logical partition-name list through HmsClient#getPartitions; the existing cache aggregates misses, one HMS batch executor owns bounded chunking, adaptive fallback and strict response validation, and a leaf transport performs one getPartitionsByNames invocation per physical attempt. Query, statistics, write and Hive-backed MTMV callers therefore receive the same batching behavior without implementing their own chunk/retry loops.

Common HMS batch execution

  • hive.hms_partitions_batch_size_per_rpc bounds each physical partition-object request; the default is 5,000.
  • Explicit message/frame/request-size and partition-limit failures halve the effective batch size until success or the minimum batch size of one.
  • The reduced successful size is reused for the remaining partitions in the logical request.
  • The reduction ladder is naturally bounded by the configured maximum and minimum batch sizes. Individual blocking calls continue to use the existing HMS connection/socket timeout; this PR does not advertise a separate fallback wall-clock deadline that cannot interrupt an active synchronous RPC.
  • Ordinary connection outages, authentication/setup failures, malformed results and local failures are not replayed through the halving ladder.
  • Hive's standard hive.metastore.limit.partition.request / “partitions scanned ... exceeds limit” failure is recognized.
  • With hive.metastore.client.pool.size=0, successful chunks in one logical request reuse one temporary HMS client. A failed physical call taints and destroys that client before a fallback attempt creates another.
  • Hive and Hudi bind and validate the same batch-size setting through HmsClientConfig.
  • Batch request and transport types remain package-private HMS implementation details.

Strict result integrity

  • Requested names are parsed once per layer into canonical ordered partition-value identities.
  • Duplicate request identities and inconsistent partition-key layouts fail before HMS access.
  • Every physical response is checked for missing, duplicate, unexpected, null and invalid-arity partition objects.
  • HMS response order is not trusted; a valid response is reconstructed in exact request order.
  • Any integrity mismatch fails the whole logical request with bounded diagnostics. Partial results are neither returned nor published to cache.
  • Mixed cache hit/miss requests fetch all misses in one logical delegate call, rebuild caller order, and retain the existing invalidation-generation fence.

Narrow MTMV bulk adapter

  • MTMVRelatedTableIf#getPartitionSnapshots has a compatibility default that retains the existing scalar loop for non-bulk table implementations.
  • The plugin-driven external-table adapter overrides it and calls the connector bulk freshness API once for the requested table/partition union.
  • Hive implements that bulk API with one logical HmsClient#getPartitions call; the common executor then splits it into bounded physical requests.
  • MTMVRefreshContext keeps only a request-scoped table → partition → snapshot cache. It unions mapped base partitions before the existing loops in sync, need-refresh, display, persistence and rewrite paths.
  • Persisted partition-name mismatches are rejected locally before remote freshness loading.
  • MTMVTask preloads the complete need-refresh union before splitting execution groups, so the default one-partition group size cannot regress first/manual/COMPLETE refreshes to singleton HMS requests.
  • Existing MTMV mapping semantics, base-version, lock and persisted-snapshot lifecycles remain unchanged. Task-captured MVCC pins are threaded through mapping/alignment and the bulk loader, and the new bulk freshness load runs outside the task's table locks.

With the default batch size, a cold 120,000-partition logical object request becomes 24 bounded requests instead of one 120,000-name request. A 160,000-partition Hive-backed MTMV union becomes one logical bulk load and 32 bounded physical requests, rather than one object request per mapped partition.

Query Profile observability

  • Hive table scans publish one aggregated Connector Metadata Access profile through the existing ConnectorScanProfile hook.
  • The profile reports logical requests and requested items, physical batch attempts and items, smallest/largest batch sizes, fallback reductions, total logical elapsed time, total batch-call elapsed time, and maximum batch-call latency.
  • Partition-batch scan mode aggregates all asynchronous 1,024-partition scan batches before publishing the profile.
  • Synchronous planning failures and asynchronous dispatch that stops before every logical batch is submitted still drain completed metadata diagnostics exactly once; profile-finalization failures do not mask the primary planning failure.
  • Cache hits remain visible as logical requested items with zero physical batch attempts.
  • The implementation returns immutable result-plus-stats data from the common executor; it does not put observers, callbacks, or mutable execution state into HmsPartitionRequest.

Scope boundaries:

  • This PR targets the master Thrift-HMS path used by Hive/Hudi. Iceberg, Paimon and non-HMS metadata protocols keep their own implementations.
  • 4.0/4.1 backports require separate path-specific changes and validation.
  • Query cancellation/deadline propagation through name listing, authentication, pool/client creation, retry and active wire calls is out of scope.
  • A separate fallback wall-clock deadline is also out of scope; implementing one correctly requires the same client-taint and late-call cleanup lifecycle as active-call cancellation.
  • Connector-wide process metrics, source tagging, and non-scan metadata spans remain out of scope; this PR adds only lightweight Hive scan Profile output through the existing scan-profile SPI.
  • Cache single-flight/admission/progressive publication, statistics sampling-policy changes and Cloud MTMV preload policy are out of scope.
  • Split-assignment first-split timeout and SplitSource lifecycle behavior are unchanged.
  • The original 120,000-partition real HMS environment has not been rerun on this commit.

Release note

Hive Metastore partition-object access now uses configurable bounded RPC batches, strict response validation, and adaptive fallback for explicit oversized-request failures. Hive-backed MTMV partition freshness is aggregated into bulk logical requests before HMS batching. Hive Query Profile also shows the resulting partition-batch request shape and elapsed time.

Deterministic request-shape evidence

Scenario Previous / unsafe shape This PR
Master 120,000-partition object load 1 unbounded request containing 120,000 names 24 requests, each at most 5,000 names
Legacy scalar caller shape, 120,000 objects Approximately 120,000 object requests 24 bounded object requests
Hive-backed MTMV, 160,000 mapped objects Approximately 160,000 singleton object requests 1 logical bulk load, split into 32 physical requests
Injected server limit above 625 names Large request fails 5000 → 2500 → 1250 → 625, then all objects complete
Pool disabled, successful multi-chunk request A new client per chunk in the initial implementation One temporary client reused for all successful chunks

These rows describe deterministic orchestration and request shape; they are not a substitute for a real 120,000-partition HMS end-to-end rerun.

Validation

  • Latest review increment: 13 HMS batch-executor tests and 20 PluginDriven scan batch/profile tests passed; Hive/Hudi catalog-property tests also passed.

  • 111 focused FE-core tests passed: MTMV refresh context, partition utilities, rewrite, task, and plugin-driven MVCC table paths.

  • 72 focused connector tests passed: HMS batching/cache/Thrift integration, Hive freshness, and connector SPI surface.

  • The final no-cache 60-module Maven validate reactor passed with zero Checkstyle violations.

  • git diff --check passed.

  • Effective PR diff against its master base: 43 files, 3,086 additions and 207 deletions, excluding the uncommitted design/review documents.

  • Three independent final review scopes converged with no new P1/P2 findings after fixing task preloading, pool-disabled client reuse, and Hive's standard partition-limit classifier.

  • Focused Maven compilation/tests reused the worktree's existing generated sources because thirdparty/installed is absent; no successful full ./build.sh --fe run is claimed.

@hello-stephen

Copy link
Copy Markdown
Contributor

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

@morrySnow morrySnow changed the title [improvement](fe) Batch Hive metastore partition access [improvement](hive) Batch Hive metastore partition access Aug 27, 2026
Issue Number: None

Related PR: None

Problem Summary: Hive tables with very large partition counts could issue one HMS RPC per partition or one unbounded getPartitionsByNames request. This caused excessive serial RPC latency and exposed Thrift message-size, timeout, memory, cancellation, cache-concurrency, and observability gaps. Add one HMS-owned bounded batch loader with adaptive halving for classified Thrift failures, strict result-integrity validation, request deadline and cancellation, physical RPC metrics, and Query Profile events. Reuse it from query, MTMV, statistics, display, and regular write partition-object paths, and coalesce concurrent cache misses per partition with bounded FIFO load slots.

Hive metastore partition-object access is now bounded, cancellable, observable, and shared across query, MTMV, statistics, display, and write paths.

- Test: Unit Test
    - HMS batch, cache, and pool tests
    - Hive metadata and transaction tests
    - MTMV and connector profile tests
- Behavior changed: Yes (large Hive partition-object reads use bounded HMS batches with adaptive fallback and strict integrity checks)
- Does this need documentation: No
@CalvinKirs

Copy link
Copy Markdown
Member Author

run buildall

@CalvinKirs

Copy link
Copy Markdown
Member Author

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes. Three review rounds converged cleanly—all final-round reviewers returned NO_NEW_VALUABLE_FINDINGS—on nine distinct issues: five P1 correctness/compatibility/capacity problems and four P2 lifecycle/observability problems. The review is complete rather than capped.

Critical checkpoint conclusions:

  • Goal and proof: the PR establishes the intended common HMS batching, integrity, cancellation, cache-coordination, and telemetry path, and the added unit tests prove many normal/error paths. The nine inline defects prevent the implementation from safely meeting the full contract.
  • Scope and clarity: this is a justified but broad 58-file cross-cutting change. The raw-loader/cache/SPI decomposition is generally clear; the remaining defects concentrate at ownership and phase boundaries.
  • Concurrency: query/MTMV/display request threads coordinate through per-key in-flight state, FIFO slots, and striped locks while HMS RPCs stay outside locks. Normal owner/waiter cleanup and lock ordering are sound, but refresh can miss a newly registered publisher, cache-disabled traffic bypasses admission, and MTMV local mapping/version capture is not atomic.
  • Lifecycle/static state: task-owned StatementContext cleanup and successful connector replacement are sound. Temporary validation contexts and superseded failed-init contexts leak shared metrics references. No C++ static-initialization concern applies.
  • Configuration: the new HMS batch/fallback properties are validated and wired consistently through Hive and Hudi; they are catalog-scoped rather than dynamic process variables. Disabling partition retention incorrectly disables the pool-derived admission bound.
  • Compatibility: the public connector SPI surface changes without the repository-mandated 7.0 major bump, so the major-only plugin gate permits incompatible 6.x linkage. No storage-format or FE/BE protocol change is present.
  • Parallel paths: all eight production partition-object callers and Hive/Hudi construction were traced. Query/write/statistics sources and sessions are propagated; SHOW/display purpose is not, and the analogous task/display MTMV phase split needs the same ownership fix.
  • Conditions and error handling: strict identity/order validation, typed integrity failures, statement deadlines, and cancellation/pool-taint boundaries are otherwise sound. The generic TTransportException condition is too broad, and the MTMV outside-lock predicate is too broad.
  • Tests and results: changed tests cover batching, fallback state, result integrity, owner/waiter cleanup, cancellation, metrics/profile aggregation, and MTMV bulk caching. Missing decisive coverage is called out inline for refresh registration, disabled-cache zero-pool concurrency, mixed/cloud mapping races, context ownership, DISPLAY, outer logical-event aggregation, and process wait metrics. Per the review prompt, I ran no build or tests. Current CI has green style/security/coverage contexts; FE UT, compile, performance, and automated review are still pending.
  • Observability: event schema/cardinality and profile serialization are generally sound, but context leaks, DISPLAY mislabelling, caller-event misaggregation, and missing process wait metrics make the advertised telemetry inaccurate.
  • Transactions, persistence, writes, and FE/BE variables: no transaction protocol, persisted schema, EditLog payload, storage format, or FE-to-BE variable was added. Replay initialization and Hive write/transaction callers were audited; their accepted issue is the shared context lifecycle leak, not transaction atomicity.
  • Performance: bounded physical batches and single-flight improve the intended large-partition path, but ordinary outages can be amplified through the halving ladder and cache-disabled zero-pool traffic can open unbounded concurrent clients.
  • Other applicable checks: this PR is FE Java only, so BE memory tracking, nullable-column handling, delete bitmaps, and C++ static/TU rules are not applicable. No additional issue survived the final changed-file and missed-path sweep.

No additional user-provided review focus was supplied.

this.rawStoragePropsSupplier =
Objects.requireNonNull(rawStoragePropsSupplier, "rawStoragePropsSupplier");
this.environment = buildEnvironment();
this.metadataAccessMetrics = new ConnectorMetadataAccessMetrics(catalogName);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Give the validation metrics reference an owner. This constructor now acquires a shared per-catalog metrics reference even for the temporary context created by forCatalogCreationValidation(). CatalogFactory passes that context inline and retains only the connector, while PluginDrivenExternalCatalog explicitly leaves connectorContext null for this validation connector, so neither initialization nor catalog teardown can call DefaultConnectorContext.close() on it. Each create/replay attempt therefore leaves an entry in SHARED_METRICS; after the live catalog records metrics, DROP also cannot unregister those catalog-labelled series because the leaked reference keeps the count nonzero. Please make validation use a non-acquiring metrics sink or give the temporary context an explicit owner that closes it on every success/failure/fallback path. The same ownership rule is also needed for live initialization: construct into a local context, publish it only after connector creation succeeds, and close it on null/throw so repeated retries cannot overwrite and leak failed contexts.

}
// Write binding gained execution-capability methods in this surface revision. A plugin built against
// major 5 must be refused rather than run against a contract it did not compile against.
// Write binding gained execution-capability methods, while metadata access gained operation control,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Bump the connector SPI major for this surface change. This PR adds methods and types to the public connector SPI, but the API is still stamped as 6.0. The policy beside connector.plugin.api.version requires a same-commit major bump for any SPI surface addition, and ApiVersionGate checks only major equality. As written, a plugin compiled against these new APIs is labelled 6.0 and can be accepted by an older 6.0 FE, then fail at first use with NoSuchMethodError/NoClassDefFoundError. Please bump the connector API major (and this assertion) to 7.0 in this commit.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for calling this out. We intentionally will not bump the connector SPI to 7.0 in this PR. The compatibility boundary should be a published connector API version, not every PR that evolves an API which is still unreleased on master. Connector SPI 6.0 was introduced on master on Aug 17, 2026, and no release tag contains that commit, so 6.0 is still the next unpublished surface; this PR updates that same pre-release surface and its frozen baseline before publication. Once 6.0 is released, a subsequent incompatible surface change must bump the major. Bumping the major once per pre-release PR would consume versions without creating a real artifact compatibility boundary. The existing major gate still correctly separates published/older major 5 plugins from the upcoming major 6 API.

try {
invalidateInFlightPartitionLoads(key -> key.matches(dbName, tableName), true);
} finally {
stateLock.unlock();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Keep registration fenced through the cache clear. The state lock is released before partitionsCache.invalidateIf() bumps the generation. A cold request can therefore register after the in-flight scan, start its HMS RPC, then let this refresh clear the cache and return; because that new batch was never marked invalid and publishOwnedPartitions() uses a direct put, its pre-clear load is cached afterward for the full TTL. The same gap exists in partition/DB/catalog invalidation. Please perform the matching cache invalidation under the same stripe(s), or capture/check a refresh epoch at owner publication, and add the mark/register/clear/publish interleaving to the concurrency tests.

}
for (Throwable current = failure.getCause(); current != null; current = current.getCause()) {
String className = current.getClass().getName();
if (className.endsWith(".TTransportException")) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Do not halve batches for every transport outage. This class-name check makes a closed/refused/reset/EOF/timeout TTransportException degradable even though reducing the payload cannot repair the connection. With the defaults, one 5,000-name offset can be replayed 13 times down to size 1 within the 30-second budget, and each logical call sits above Hive's own retry/reconnect proxy and may create/taint another client. That amplifies an HMS outage precisely while it is unhealthy. Please restrict fallback to explicit frame/message/request/partition-limit signals (or a proven oversize transport code), and make ordinary transport failures terminate after the original logical attempt.

int start = 0;
private void loadMissingPartitions(HmsPartitionRequest request, List<String> initialMissNames,
Map<List<String>, HmsPartitionInfo> resultByIdentity) {
if (!partitionsCache.isEffectiveEnabled()) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Preserve load admission when partition caching is disabled. This early return skips both single-flight retention and the new window/slot limiter. In the supported hive.metastore.client.pool.size=0 configuration, the constructor deliberately converts zero to one cold-load slot, but every disabled-cache request now bypasses that slot and ThriftHmsClient creates a fresh client per call; N concurrent scans/freshness probes can therefore open N HMS connections. Please keep windowing and slot admission on this path while skipping only cache coordination/publication, and cover zero-pool plus disabled cache concurrently.

MTMVPartitionUtil.addPartition(mtmv, partitionKeyDesc);
}
}
boolean buildContextUnderLock = Config.isNotCloudMode()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Keep local PCT mappings atomic with their versions in mixed MVs. This condition moves the entire context build outside the sorted table locks whenever any base table is MVCC. If the actual PCT table is a local OlapTable, its mapping is copied here at T1, external preload can then block, and the later locked refreshLocalBaseVersions() refreshes only versions—not partitionMappings. A local partition dropped in that window remains in the mapping and makes the locked version lookup fail; an added partition is omitted from comparison/refresh. The base code built both together under the locks. Please split the capture so external pins/I/O stay outside, while local PCT mappings and versions are rebuilt together under the sorted FE locks. Cloud local-only plans also always take this branch and the refresh helper is a no-op there, so preserve an atomic cloud capture as well. Apply the same fix to the analogous PartitionsProcDir branch and add mixed local-PCT/external-MVCC plus cloud local-only race tests.

}
HiveTableHandle hiveHandle = (HiveTableHandle) handle;
List<HmsPartitionInfo> partitions = hmsClient.getPartitions(
session, HmsPartitionAccessSource.MTMV,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Preserve the display source in freshness telemetry. SHOW PARTITIONS now builds and preloads MTMVRefreshContext, reaches these freshness methods, and is always emitted as MTMV here; the sibling whole-table freshness call is hard-coded the same way. There is no production use of the newly added HmsPartitionAccessSource.DISPLAY, so display traffic is indistinguishable from refresh/rewrite work in both process metrics and Query Profile despite the per-source observability contract. Please thread the logical access purpose into this freshness request and emit DISPLAY for the proc/display path, with a production-chain test.

request, initialMissNames, partitionsCache.invalidationGeneration(), resultByIdentity);
return;
}
for (int offset = 0; offset < initialMissNames.size(); offset += partitionLoadWindowSize) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Emit one logical event for the caller's request. The cache splits one business request into partitionLoadWindowSize windows and each copied request invokes the raw loader, whose finally records a completed logical event. A cold 12,000-name call therefore increments LogicalRequests three times; if the third window fails, the single caller-visible request is reported as two successes plus one failure. The cache-disabled path reports the same call once, so success rates and requested-item metrics depend on cache configuration rather than business semantics. All-hit and pure-waiter calls emit no completed business event, and mixed hit/miss calls report only owner misses. Please move event ownership to the outer cache call, aggregate the shared business-request state, and emit exactly once while retaining physical-attempt counters; test all-hit, mixed, pure-waiter, and multi-window later-failure cases.

.success(success)
.build();
try {
request.getMetadataAccessObserver().record(event);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Publish coordination waits to process metrics too. Both in-flight and cold-load-slot wait events are recorded only through the request observer, which is a Query Profile sink and becomes NOOP when profiling is disabled. The catalog observer used by the raw loader never reaches this cache layer, so FE metrics permanently omit both newly advertised wait operations even while reporting their downstream HMS call. Please give the cache the catalog observer and safely publish these events to both sinks, with process-metric coverage when query profiling is disabled.

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-H: Total hot run time: 16850 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit 7ab8c5329b97a6ac3e9361e593383e5ac0bf6bd8, data reload: false

------ Round 1 ----------------------------------
============================================
q1	17583	3020	3025	3020
q2	2100	270	226	226
q3	10222	897	526	526
q4	4671	247	197	197
q5	7682	574	392	392
q6	140	117	94	94
q7	536	492	389	389
q8	9250	860	894	860
q9	3447	2396	2410	2396
q10	6485	833	706	706
q11	391	193	188	188
q12	610	263	197	197
q13	18132	1515	1184	1184
q14	160	152	135	135
q15	q16	435	398	365	365
q17	1376	910	847	847
q18	3069	2220	2231	2220
q19	1110	863	810	810
q20	360	287	200	200
q21	5262	1666	1890	1666
q22	316	266	232	232
Total cold run time: 93337 ms
Total hot run time: 16850 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	3413	3329	3329	3329
q2	503	381	366	366
q3	2213	2368	2199	2199
q4	1175	1150	875	875
q5	2185	2084	2086	2084
q6	171	124	85	85
q7	1012	916	870	870
q8	1590	1391	1384	1384
q9	3121	3052	3054	3052
q10	1832	1787	1618	1618
q11	356	269	248	248
q12	449	428	345	345
q13	1474	1549	1160	1160
q14	177	179	158	158
q15	q16	396	400	368	368
q17	3558	3369	3290	3290
q18	4827	4392	4680	4392
q19	921	816	891	816
q20	1015	955	813	813
q21	3728	3037	3213	3037
q22	402	347	322	322
Total cold run time: 34518 ms
Total hot run time: 30811 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 81114 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit 7ab8c5329b97a6ac3e9361e593383e5ac0bf6bd8, data reload: false

query5	4269	418	341	341
query6	399	133	120	120
query7	4934	397	235	235
query8	310	130	125	125
query9	8692	2849	2837	2837
query10	392	215	181	181
query11	5392	1026	924	924
query12	128	71	76	71
query13	1212	411	323	323
query14	5966	2163	2055	2055
query14_1	1951	1935	1913	1913
query15	171	122	113	113
query16	922	361	345	345
query17	805	459	386	386
query18	2320	315	235	235
query19	165	128	109	109
query20	70	66	68	66
query21	206	105	89	89
query22	5471	5328	5327	5327
query23	6726	6139	6044	6044
query23_1	5966	5934	5926	5926
query24	7315	1101	742	742
query24_1	773	759	770	759
query25	407	289	266	266
query26	1227	234	125	125
query27	2799	430	253	253
query28	4690	1488	1450	1450
query29	913	417	327	327
query30	253	156	128	128
query31	811	399	323	323
query32	128	82	73	73
query33	454	209	180	180
query34	983	810	477	477
query35	397	394	334	334
query36	572	569	521	521
query37	122	81	72	72
query38	1001	836	805	805
query39	468	497	473	473
query39_1	461	482	453	453
query40	201	94	101	94
query41	53	51	52	51
query42	71	69	69	69
query43	234	235	209	209
query44	1023	547	545	545
query45	106	105	96	96
query46	781	833	510	510
query47	753	774	705	705
query48	318	297	245	245
query49	559	255	174	174
query50	734	253	191	191
query51	8039	7849	7942	7849
query52	69	67	60	60
query53	195	191	151	151
query54	220	199	170	170
query55	73	57	55	55
query56	217	166	171	166
query57	692	641	689	641
query58	215	187	171	171
query59	1215	1225	1101	1101
query60	268	196	191	191
query61	140	135	139	135
query62	364	218	181	181
query63	170	142	142	142
query64	2970	803	687	687
query65	1689	1632	1602	1602
query66	1973	346	222	222
query67	9817	9614	9606	9606
query68	2909	1172	712	712
query69	347	219	183	183
query70	680	604	615	604
query71	248	178	164	164
query72	2301	1378	1557	1378
query73	637	574	349	349
query74	1980	1203	1138	1138
query75	1164	1087	943	943
query76	2312	730	555	555
query77	244	251	220	220
query78	3966	3569	3076	3076
query79	2699	800	571	571
query80	1559	328	273	273
query81	496	154	134	134
query82	630	121	99	99
query83	270	206	190	190
query84	291	114	91	91
query85	823	357	299	299
query86	470	183	159	159
query87	1020	971	876	876
query88	2830	2086	2103	2086
query89	280	198	175	175
query90	2015	129	127	127
query91	127	120	99	99
query92	95	72	61	61
query93	1443	1065	703	703
query94	617	254	215	215
query95	528	266	229	229
query96	836	572	269	269
query97	1025	1120	1015	1015
query98	174	133	130	130
query99	419	348	310	310
Total cold run time: 178282 ms
Total hot run time: 81114 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
ClickBench: Total hot run time: 14.48 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit 7ab8c5329b97a6ac3e9361e593383e5ac0bf6bd8, data reload: false

query1	0.00	0.00	0.01
query2	0.08	0.04	0.03
query3	0.24	0.11	0.11
query4	1.60	0.09	0.10
query5	0.18	0.16	0.16
query6	1.25	0.67	0.72
query7	0.03	0.00	0.01
query8	0.04	0.02	0.04
query9	0.29	0.21	0.22
query10	0.33	0.35	0.35
query11	0.16	0.11	0.10
query12	0.15	0.12	0.12
query13	0.30	0.30	0.30
query14	0.44	0.45	0.43
query15	0.35	0.34	0.34
query16	0.22	0.23	0.25
query17	0.67	0.68	0.73
query18	0.18	0.15	0.16
query19	1.16	1.08	1.05
query20	0.01	0.01	0.01
query21	15.43	0.14	0.11
query22	5.08	0.05	0.04
query23	16.16	0.25	0.10
query24	3.04	0.32	0.26
query25	0.12	0.04	0.03
query26	0.81	0.16	0.13
query27	0.02	0.02	0.04
query28	3.61	0.54	0.27
query29	12.48	3.13	2.55
query30	0.26	0.12	0.14
query31	2.76	0.36	0.17
query32	3.51	0.32	0.23
query33	1.36	1.39	1.41
query34	15.35	2.15	1.80
query35	1.76	1.70	1.71
query36	0.46	0.30	0.28
query37	0.07	0.05	0.05
query38	0.05	0.03	0.02
query39	0.03	0.02	0.02
query40	0.13	0.09	0.08
query41	0.08	0.02	0.02
query42	0.03	0.02	0.02
query43	0.04	0.03	0.02
Total cold run time: 90.32 s
Total hot run time: 14.48 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 71.59% (315/440) 🎉
Increment coverage report
Complete coverage report

@CalvinKirs

Copy link
Copy Markdown
Member Author

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Request changes. Three review rounds converged with four additional issues: one P1 cancellation/lifecycle gap and three P2 compatibility/performance gaps. I did not duplicate the eight existing issue threads; their unresolved blockers remain part of this verdict. The live PR still matches the authoritative bundle at head 7ab8c5329b97a6ac3e9361e593383e5ac0bf6bd8. Current CI has compile, FE UT, CheckStyle, P0, non-concurrent, vault, and performance checks passing, while External Regression and cloud_p0 are failing.

Critical checkpoint conclusions:

  • Goal and proof: The PR implements batched/cached HMS partition freshness, cooperative cancellation, telemetry, and MTMV bulk snapshot loading, and its unit tests prove many component paths. It does not fully achieve the stated bounded/large-scale behavior because client construction remains outside cancellation/deadline control, the cache-backed scale path repeats canonicalization, and MTMV can eagerly load a huge union before a locally decisive stale gate.
  • Scope and focus: The 58-file connector/HMS/MTMV change is internally related but not yet safely mergeable. The user focus file contained no additional focus request; the full PR was reviewed.
  • Concurrency and thread safety: Enabled-cache owner/waiter futures, permits, publication, retry cleanup, and lock ordering otherwise balance. Existing threads already cover the cache-invalidation fence and disabled-cache admission bypass; the new P1 below covers synchronous client creation before cancellation can act. Heavy external work is generally moved outside FE locks, subject to the existing mixed local/cloud atomicity thread.
  • Error handling: Strict result-integrity failures and cancellation propagation are fail-loud and preserve causes in the inspected paths. The existing broad transport-fallback thread and the new eager-preload ordering can still amplify or surface avoidable HMS failures.
  • Lifecycle: Watchdog ThreadLocal cleanup, interrupt ownership, pooled-client taint/return, statement pins/scopes, and normal connector-context close were traced. Existing metrics-reference ownership remains a live thread; any fix for client creation must destroy a late result after cancellation, deadline, or concurrent close.
  • Configuration and dynamic behavior: Hive and Hudi bind the same positive batch/timeout properties and defaults through catalog construction/replay. No additional dynamic-update divergence survived review.
  • Compatibility and rolling upgrade: Default SPI methods preserve old implementation linkage, and the existing API-major thread includes the unreleased-6.0 context. Separately, the frozen-surface test omits the new reachable session/control/observer/event/abort contracts and metadata return types, so future incompatible drift can evade the gate.
  • Parallel paths: Query, statistics, MTMV, and write callers plus Hive/Hudi construction were checked. Rewrite, task, metadata/global sync, and proc/display MTMV paths were all traced. The existing DISPLAY-source thread remains the only distinct source-label issue.
  • Special conditionals: Excluded-table and PCT-first comparison semantics are intentional. Existing review context covers transport degradability and cache-disabled branching; the new MTMV finding covers preload ordering before the name-set condition.
  • Test coverage: Added tests cover batching, strict ordering, cache coordination, pool wait cancellation, metrics/profile aggregation, context capture, and 160k aggregation. Missing cases are identified inline: blocking client creation, frozen reachable SPI contracts, cache-backed parse counts, and large name-set mismatch with zero freshness calls.
  • Test results: This review-only environment expressly prohibited builds/tests, so none were run here. No regression .out files changed. Live FE UT/compile/style checks pass, but External Regression and cloud_p0 currently fail.
  • Observability: Process metrics and Query Profile coverage were inspected. Existing threads cover metric reference ownership, fragmented logical events, missing process wait metrics, and DISPLAY attribution; no additional observability issue survived.
  • Transaction and persistence: MTMV refresh snapshot generation, manual/COMPLETE refresh, current-relation resolution, and per-partition persistence inputs were traced. No new EditLog schema is introduced; the existing MTMV mapping/version atomicity thread remains applicable.
  • Data writes and crash behavior: No new BE/storage data-write path is introduced. MTMV refresh scheduling and snapshot capture were checked; no distinct crash leak or partial-write issue survived beyond the live atomicity/lifecycle threads.
  • FE/BE variables: No new FE-to-BE variable or protocol field is introduced.
  • Memory safety and nullable handling: The change is Java/FE-only; BE allocator, C++ lifetime, and nullable-column checkpoints are not applicable. Java ownership and large temporary allocations were reviewed, with the repeated identity allocation issue called out inline.
  • Data correctness: Strict partition identity, duplicate, missing, unexpected, and ordering checks are coherent. Existing threads cover cache freshness fencing and MTMV atomicity; the dismissed display snapshot split predates this PR.
  • Performance: Batching removes per-partition RPCs, but the cache-backed request performs 3N parses on all hits and 6N+C when fully cold, and MTMV may issue a 160k-name freshness load before a set mismatch already proves staleness.
  • Other issues and completion: All candidates are accepted, deduplicated, or dismissed with code evidence. Round 3 ended with NO_NEW_VALUABLE_FINDINGS from both normal full reviews and the independent risk review, so this review is complete.

waitMillis = Math.min(waitMillis, operationRemainingMillis);
}
try {
return clientPool.borrowObject(waitMillis);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Bound HMS client creation with the operation control. On an empty pool, Commons Pool 2.2 runs HmsClientFactory.create() synchronously inside borrowObject(waitMillis) before the timed idle-object wait, so waitMillis does not bound createFreshClient(); the pool-disabled branch calls it directly as well. Kerberos login, DNS, or socket construction can therefore remain stuck after KILL/deadline, before HmsRemoteCallTracking installs its watchdog and before the next checkActive(). Please make creation cancellable/deadline-aware (and destroy any client that completes late) for both branches, with blocking-provider KILL/deadline tests.

return ConnectorStatementScope.NONE;
}

/** Returns cooperative cancellation and deadline control for connector metadata operations. */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Freeze the new session/control API in the plugin surface. ConnectorPluginSurfaceTest.FROZEN_TYPES does not include ConnectorSession or the new control/observer/event/abort types, so the regenerated baseline records ConnectorContext#getMetadataAccessObserver() but not these two session methods or the callable contracts they expose. The separate metadata baseline also omits return types. That leaves later removal/re-signing of this new 6.0 surface invisible to the stated compatibility speed bump. This is independent of whether 6.0 is still unpublished: please freeze these reachable SPI types (or recursively freeze reachable SPI contracts), regenerate the baseline, and assert the new methods are present.

operationControl.checkActive();
}
String partitionName = partitionNames.get(i);
HmsPartitionIdentity.ParsedPartitionName parsed = HmsPartitionIdentity.parse(partitionName);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Retain parsed identities across the cache-backed request. This builder validates every partition name with HmsPartitionIdentity.parse() and then discards the result. The normal cold-cache path reparses all names during cache lookup, registration, copied-window construction, raw validation, and final reconstruction—6N+C parse/unescape passes for a fully cold sole owner (roughly 720k canonicalizations for 120k names); even all hits take 3N. The added 120k test covers only the raw loader, so it misses this decorator cost. Please carry immutable parsed keys/values on the request and share/slice them through windows and validation, with a cache-backed large-request parse-count/performance test.

throws AnalysisException {
MTMV mtmv = context.getMtmv();
Set<String> partitionNames = mtmv.getPartitionNames();
context.preloadSnapshots(partitionNames, tables, excludeTables);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Check the persisted partition set before eager freshness loading. This preload fetches partition-detail freshness for the entire mapped PCT union before isSyncWithPartitions() compares the current names with the persisted getPctSnapshots() set. With a coarse mapping over 160k Hive partitions, adding or dropping one partition already proves the MTMV stale locally, but this order now issues the full HMS freshness request first (and can fail before returning that deterministic stale result); the pre-PR path performed the set gate before fetching snapshots. Please make the comparison two-phase—reject name-set mismatches first, then preload only mappings that still need version checks—and add large mismatch coverage asserting no partition-freshness call.

@CalvinKirs

Copy link
Copy Markdown
Member Author

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the authoritative 58-file bundle and all live/raw review comments through three convergence rounds. Two additional non-duplicate issues remain, alongside the unresolved live blockers, so I am requesting changes.

Key checkpoints: the cross-layer scope matches the stated bounded/cancellable HMS-load and MTMV-freshness goal, and the new request, loader, control, telemetry, and refresh-context helpers generally keep responsibilities clear. Strict response validation/order, typed cancellation, cache/pool cleanup, connector construction, statement-scope closure, and the main query/statistics/scan/write/refresh/rewrite/display paths were traced. The remaining new gaps are (1) rewrite eagerly loading locally rejectable candidates while planner locks are held and (2) equivalent waiters serially replaying a shared integrity failure. Existing threads already fence the other identified concurrency, invalidation, compatibility, metrics, and eager-loading concerns. Hive/Hudi configuration validation and SPI forwarding were checked; this patch changes no storage/EditLog format, transaction protocol, FE/BE wire value, or BE memory/nullability path.

No local build or tests were run because the review bundle forbids them. Current checks show FE UT, compile, P0, nonconcurrent, and vault passing; External Regression and cloud_p0 are failing, with no public failure detail available from the linked TeamCity endpoints. The changed unit tests cover most raw/cache/control and MTMV batch paths, but not the two concurrent/production-chain cases called out inline.

Comment thread fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRewriteUtil.java Outdated
### What problem does this PR solve?

Issue Number: None

Related PR: apache#67186

Problem Summary: The shared Hive metastore partition batch path still had lifecycle, concurrency, compatibility, and MTMV freshness edge cases found during review. Blocking HMS client construction could outlive cancellation, parsed identities were repeatedly rebuilt in cache windows, equivalent waiters could replay terminal integrity failures, and rewrite or refresh paths could preload metadata before deterministic stale gates. This change makes client creation operation-controlled, reuses immutable parsed identities, scopes waiter retries, applies persisted-set gates before freshness loading, and completes SPI and metrics lifecycle coverage.

### Release note

Hive metastore partition batching now has stronger cancellation, concurrent failure sharing, MTMV freshness gating, and connector SPI compatibility checks.

### Check List (For Author)

- Test: Unit Test
    - Targeted FE unit tests for HMS cache concurrency, pool control, batch loading, MTMV rewrite and refresh, metrics, and Connector SPI surface
- Behavior changed: Yes. Equivalent cache waiters share terminal integrity failures, narrower waiters retry independently, and MTMV rewrite skips freshness loads for locally rejected candidates.
- Does this need documentation: No
### What problem does this PR solve?

Issue Number: None

Related PR: apache#67186

Problem Summary: The new connector metadata access source import was placed before lexicographically earlier HMS and connector SPI imports in three Hive connector classes, causing the full FE CheckStyle workflow to fail. Reorder those imports according to the Doris CustomImportOrder rule.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - cd fe && mvn clean checkstyle:check
- Behavior changed: No
- Does this need documentation: No
@CalvinKirs

Copy link
Copy Markdown
Member Author

/review

@github-actions

Copy link
Copy Markdown
Contributor

Codex automated review failed and did not complete.

Error: Your access token could not be refreshed because your refresh token was revoked. Please log out and sign in again.
Workflow run: https://github.com/apache/doris/actions/runs/33137288710

Please inspect the workflow logs and rerun the review after the underlying issue is resolved.

@CalvinKirs

Copy link
Copy Markdown
Member Author

run buildall

@CalvinKirs

Copy link
Copy Markdown
Member Author

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes for four distinct current-head issues: unbounded outstanding HMS client creators, MTMV persistence losing union batching on first/incomplete or mapping-changed baselines, cloud version RPCs under FE table locks, and nested wait spans inflating the legacy metadata-time total.

Checkpoint conclusions:

  • Goal, focus, and scope: the common bounded HMS path is broadly wired across query, statistics, MTMV, display, transaction, and write callers; no extra user focus was supplied. The first-refresh persistence case still misses the central batching goal.
  • Correctness, conditions, and parallel paths: strict identity/order validation and migrated Hive/Hudi caller paths were checked, including cache-enabled/disabled, pooled/unpooled, first/incomplete/changed MTMV snapshots, local/external/cloud, and success/failure/cancellation branches.
  • Concurrency and lifecycle: cache owner/waiter, invalidation, slot, retry, and publication paths were reviewed. The asynchronous creation fix has no bound on interrupt-ignoring creator tasks.
  • Configuration and compatibility: new property defaults/validation, source/control defaults, connector SPI freezes, and the unreleased-6.0 compatibility context were checked. No new FE-BE wire dependency was introduced.
  • Observability and performance: detailed operation counters remain useful, but the legacy query total double-counts nested waits. The first/incomplete MTMV path can turn a 160k disjoint mapping into roughly 160k logical one-name freshness requests.
  • Transactions, persistence, writes, and atomicity: transaction/write callers use the common API; snapshot persistence has the separate preload-mode bug below, and cloud recapture performs remote work inside metadata locks. Existing live atomicity threads were treated as duplicate fences.
  • Tests/results: reviewed the changed unit tests and the PR's reported 250-partition manual profile. No build or test command was run in this review, as required by the review task; the PR also states the 120k end-to-end case was not rerun. Missing focused coverage is called out inline.

A complete 63-file final sweep and a second full convergence round found no additional distinct issues beyond these four and existing review threads.

Comment thread fe/fe-core/src/main/java/org/apache/doris/common/profile/SummaryProfile.java Outdated
Comment thread fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRefreshContext.java Outdated
Comment thread fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRefreshContext.java Outdated
@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-H: Total hot run time: 17284 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit 1cd171d3667c98af0dd494649fece917b5cb921a, data reload: false

------ Round 1 ----------------------------------
============================================
q1	17566	3068	3029	3029
q2	2102	254	237	237
q3	10223	868	526	526
q4	4672	258	200	200
q5	7674	590	392	392
q6	137	119	96	96
q7	521	526	393	393
q8	9232	920	945	920
q9	3511	2432	2442	2432
q10	6499	884	758	758
q11	402	201	182	182
q12	625	262	201	201
q13	18119	1539	1167	1167
q14	163	157	145	145
q15	q16	447	407	376	376
q17	1310	883	854	854
q18	3171	2293	2285	2285
q19	1117	929	833	833
q20	372	306	204	204
q21	4864	1820	1917	1820
q22	344	277	234	234
Total cold run time: 93071 ms
Total hot run time: 17284 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	3395	3344	3325	3325
q2	541	413	393	393
q3	2229	2393	2216	2216
q4	1232	1198	923	923
q5	2254	2165	2142	2142
q6	172	119	88	88
q7	1088	962	897	897
q8	1641	1452	1440	1440
q9	3213	3186	3159	3159
q10	1890	1832	1665	1665
q11	363	277	263	263
q12	460	442	350	350
q13	1484	1537	1195	1195
q14	172	183	161	161
q15	q16	419	407	367	367
q17	3693	3458	3289	3289
q18	4927	4535	4949	4535
q19	960	895	874	874
q20	1028	1033	850	850
q21	3990	3238	3283	3238
q22	418	362	333	333
Total cold run time: 35569 ms
Total hot run time: 31703 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 83713 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit 1cd171d3667c98af0dd494649fece917b5cb921a, data reload: false

query5	4299	447	343	343
query6	396	143	137	137
query7	4887	419	235	235
query8	303	128	124	124
query9	8676	3019	2998	2998
query10	393	237	191	191
query11	5417	1064	919	919
query12	138	75	72	72
query13	1184	448	330	330
query14	6092	2299	2143	2143
query14_1	2048	2034	2032	2032
query15	178	122	114	114
query16	951	385	362	362
query17	830	453	388	388
query18	2333	330	246	246
query19	163	142	113	113
query20	74	70	71	70
query21	212	104	90	90
query22	5358	5436	5360	5360
query23	6849	6320	6255	6255
query23_1	6229	6414	6096	6096
query24	7305	1118	797	797
query24_1	810	809	813	809
query25	449	319	272	272
query26	1236	240	137	137
query27	2779	424	265	265
query28	4674	1510	1518	1510
query29	943	465	372	372
query30	252	158	131	131
query31	830	410	345	345
query32	134	76	80	76
query33	476	237	196	196
query34	974	839	524	524
query35	404	400	350	350
query36	579	606	547	547
query37	124	80	71	71
query38	1023	859	818	818
query39	506	488	491	488
query39_1	473	491	481	481
query40	209	92	76	76
query41	53	57	55	55
query42	74	70	75	70
query43	242	247	213	213
query44	1021	550	578	550
query45	114	109	97	97
query46	793	804	532	532
query47	781	762	715	715
query48	320	315	218	218
query49	554	253	186	186
query50	727	273	195	195
query51	8004	8045	8124	8045
query52	68	70	59	59
query53	191	204	146	146
query54	238	281	153	153
query55	73	58	57	57
query56	216	185	163	163
query57	709	632	639	632
query58	197	174	165	165
query59	1243	1252	1117	1117
query60	244	191	186	186
query61	122	168	134	134
query62	381	222	179	179
query63	168	153	139	139
query64	2684	699	612	612
query65	1711	1571	1652	1571
query66	1774	263	217	217
query67	9865	9767	9849	9767
query68	3014	1265	739	739
query69	345	225	202	202
query70	675	617	614	614
query71	250	178	166	166
query72	2469	1791	1660	1660
query73	654	576	340	340
query74	2015	1217	1172	1172
query75	1217	1142	992	992
query76	2367	744	562	562
query77	270	265	218	218
query78	3935	3634	3252	3252
query79	2351	869	606	606
query80	1652	362	322	322
query81	497	161	138	138
query82	641	133	101	101
query83	335	215	189	189
query84	293	111	91	91
query85	843	370	315	315
query86	396	174	179	174
query87	1045	992	904	904
query88	2806	2140	2125	2125
query89	292	199	178	178
query90	1943	132	133	132
query91	135	126	104	104
query92	82	71	71	71
query93	1500	1171	725	725
query94	663	287	245	245
query95	534	329	233	233
query96	838	612	272	272
query97	1120	1094	1042	1042
query98	166	132	135	132
query99	416	351	315	315
Total cold run time: 178917 ms
Total hot run time: 83713 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
ClickBench: Total hot run time: 14.96 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit 1cd171d3667c98af0dd494649fece917b5cb921a, data reload: false

query1	0.00	0.01	0.00
query2	0.08	0.04	0.04
query3	0.24	0.11	0.11
query4	1.60	0.11	0.10
query5	0.17	0.16	0.16
query6	1.24	0.71	0.73
query7	0.04	0.01	0.00
query8	0.06	0.03	0.03
query9	0.30	0.22	0.22
query10	0.36	0.36	0.35
query11	0.17	0.11	0.11
query12	0.14	0.12	0.12
query13	0.31	0.31	0.32
query14	0.46	0.48	0.47
query15	0.37	0.36	0.36
query16	0.24	0.22	0.23
query17	0.71	0.74	0.69
query18	0.18	0.16	0.15
query19	1.24	1.19	1.15
query20	0.02	0.01	0.01
query21	15.43	0.18	0.13
query22	5.02	0.05	0.04
query23	16.19	0.25	0.11
query24	3.00	0.30	0.24
query25	0.11	0.03	0.03
query26	0.78	0.17	0.12
query27	0.04	0.03	0.03
query28	3.59	0.56	0.28
query29	12.44	3.19	2.59
query30	0.25	0.11	0.12
query31	2.76	0.39	0.18
query32	3.50	0.31	0.24
query33	1.40	1.41	1.65
query34	15.40	2.27	1.82
query35	1.83	1.78	1.78
query36	0.48	0.30	0.31
query37	0.06	0.04	0.04
query38	0.05	0.03	0.03
query39	0.03	0.02	0.03
query40	0.11	0.08	0.07
query41	0.08	0.04	0.03
query42	0.03	0.02	0.02
query43	0.03	0.03	0.03
Total cold run time: 90.54 s
Total hot run time: 14.96 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 70.45% (379/538) 🎉
Increment coverage report
Complete coverage report

### What problem does this PR solve?

Issue Number: None

Related PR: apache#67186

Problem Summary: Review found four remaining correctness and resource-control gaps in the shared HMS partition batch work. Nested coordination spans double-counted legacy profile time, non-cooperative HMS client creation could grow unbounded daemon threads, MTMV snapshot persistence skipped union preloading for first or changed baselines, and cloud MTMV version refreshes could issue remote calls while FE table locks were held. Count only top-level HMS access in legacy totals, retain bounded client-creation admission until real creator exit, split persistence preloading from comparison gating, and preload cloud MTMV versions before locks while revalidating locked structure from raw local caches.

### Release note

Improve HMS partition batch profiling, cancellation resource bounds, MTMV snapshot batching, and cloud lock behavior.

### Check List (For Author)

- Test: Unit Test
    - SummaryProfileTest, ThriftHmsClientPoolControlTest, MTMVRefreshContextBatchTest, MTMVPartitionUtilTest, MTMVRewriteUtilTest, PreloadExternalMetadataTest (46 tests)
    - MTMVTaskTest and PartitionsProcDirTest (18 tests)
    - cd fe && mvn clean checkstyle:check
- Behavior changed: Yes. Legacy profile totals no longer double-count nested waits, HMS creators are bounded, persistence uses ungated union preloading, and cloud version RPCs run before FE table locks.
- Does this need documentation: No
@CalvinKirs

Copy link
Copy Markdown
Member Author

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed exact head 43bed7de746e1c13586452e3b22b5ea539cd9f58 against base 7219c67265bc700c1457b3339c6a9d0143d36c1f.

Requesting changes for three distinct P2 issues in the new HMS statistics, MTMV bulk-freshness, and scan-profile paths.

Critical checkpoint conclusions:

  • Goal and scope: all 44 authoritative changed paths were reviewed. The patch substantially achieves bounded/adaptive partition-object reads, exact versus omission-tolerant validation, cache-safe publication, MTMV bulk reuse, and query-profile aggregation, subject to the three inline failure/observability regressions.
  • Concurrency and lifecycle: cache publication/invalidation leases, pooled and pool-size-zero client retirement, per-scan synchronized aggregation, atomic submitted-task finalization, and request-scoped MTMV caches were traced. Heavy HMS/filesystem work remains outside the reviewed locks, no new lock-order cycle was found, and existing live threads fence earlier lifecycle concerns.
  • Configuration and compatibility: hive.hms_partitions_batch_size_per_rpc reaches both live Hive and Hudi client builders with consistent positive validation. The connector bulk-freshness method has a scalar default and an updated surface baseline; the prior API-major discussion is already covered by a live thread. No FE/BE protocol or storage-format change applies.
  • Parallel and conditional paths: exact transaction-owned reads, omission-tolerant scan/freshness/write-plan reads, raw/cached and pooled/unpooled clients, task/rewrite/display/persistence MTMV callers, synchronous/batch/prune-to-zero scans, fallback, terminal failure, and cleanup paths were checked. Remaining non-inline concerns are either disproved or duplicate-fenced.
  • Tests and observability: changed tests cover large/trailing/adaptive batches, integrity and omission contracts, cache invalidation fencing, unpooled reuse/cleanup, pin/cache reuse, and provider-stage profile success/failure. They do not cover the three inline triggers: pre-wire/retry-proxy RPC counts, partial-union rewrite failure isolation, and pruning failure before provider creation. No builds or tests were run because the review prompt explicitly prohibited them; available static CI checks on this head are green.
  • Persistence, transactions, and writes: no EditLog or data-write protocol change is introduced. Transaction-owned partition identities remain exact, and MTMV snapshot persistence remains strict; any rewrite-isolation repair must preserve persistence completeness.
  • Performance and other correctness: remote payloads are bounded and request parsing, validation, and reconstruction remain linear. Previously reported eager/lock-held MTMV work and other profile concerns were not duplicated. No additional security, memory, configuration-observation, or material performance issue survived the final sweep.

The review converged after two rounds: every candidate was accepted, dismissed with production-path evidence, or hard-deduplicated against the live discussions. The user focus file supplied no additional focus points.

for (HmsPartitionIdentity.ParsedPartitionName partition : batch) {
batchNames.add(partition.getName());
}
attempts++;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Do not report transport invocations as physical HMS RPCs. These counters and the RPC timer start before transport.getPartitionsByNames; the pooled path can then fail in borrowClient, fresh-client creation, or outer authentication without calling HMS at all, while the default RetryingMetaStoreClient can perform multiple wire attempts inside one invocation. The Query Profile can therefore show one RpcAttempt/all RpcItems for zero wire calls, or undercount retries, and RpcElapsedTime includes setup/pool wait despite the new API documenting physical-attempt statistics. Instrument actual client attempts (including retries), or rename/separate these as batch-invocation and setup metrics, with pre-wire-failure and retry coverage.

if (!withinGracePeriod && mtmvNeedComparePartitions.contains(candidate.getName())) {
partitionsToPreload.add(candidate.getName());
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Preserve per-partition rewrite failure isolation. This rewrite-wide preload sits outside the loop's existing checked-failure boundary. With mv1 -> p1 and mv2 -> p2, if p1 disappears after the pin, Hive's omission-tolerant bulk result can still contain p2, but getPartitionSnapshots throws for p1 and this catch returns before mv2 is evaluated. The previous scalar lookup threw inside the per-partition try, so only mv1 was skipped. Please retain per-name bulk outcomes (for example, defer missing-name errors to PreparedPartitionSnapshots#get) and add a two-partition pin/drop test proving the unaffected partition remains rewritable.


List<HmsPartitionInfo> prunedPartitions = matchedPartNames.isEmpty()
? Collections.emptyList()
: hmsClient.getPartitions(hiveHandle.getDbName(),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Preserve failed pruning stats before the scan provider exists. A selective equality-pruning request can perform HMS batches and then throw a stats-bearing HmsClientException here, before a new handle or HiveScanPlanProvider is created. convertPredicate propagates that failure, so the synchronous/batch finalizers never run and the Query Profile omits the request that aborted planning. The existing fixes cover successful pruning handoff and failures inside planScan, not this earlier boundary. Establish the scan-scoped profile owner before filter pushdown (or otherwise publish the attached stats while preserving the primary exception), and add a production-chain failing-prune test.

### What problem does this PR solve?

Issue Number: None

Related PR: apache#67186

Problem Summary: Concurrent cold partition scans could issue duplicate HMS loads after the cache unification, MTMV bulk snapshot preload widened one missing partition into a rewrite-wide or task-wide failure, pruning failures could lose their HMS batch profile before a scan provider existed, and profile fields described transport invocations as physical RPC attempts. Restore per-partition owner/waiter coordination with invalidation-aware bulk fences, retain MTMV snapshot outcomes per partition, transfer pruning failures through statement scope, and rename the metrics to their actual transport semantics.

### Release note

HMS partition profile metrics now use TransportInvocations, TransportItems, TransportElapsedTime, and MaxTransportElapsedTime.

### Check List (For Author)

- Test: Unit Test
    - Added concurrency, invalidation, MTMV partial-outcome, and pruning-profile handoff coverage. The focused run-fe-ut.sh execution was attempted but stopped before Java compilation because this worktree is missing thirdparty/installed/bin/protoc.
- Behavior changed: Yes. Concurrent partition loads are coalesced, MTMV missing-partition failures are isolated by partition, pruning failures publish profiles, and HMS profile metric names are corrected.
- Does this need documentation: No
@CalvinKirs

Copy link
Copy Markdown
Member Author

/run buildall

### What problem does this PR solve?

Issue Number: None

Related PR: apache#67186

Problem Summary: The MTMV partial-result change stopped constructing an ArrayList in PluginDrivenMvccExternalTable but left the import behind, causing the FE CheckStyle workflow to fail. Remove the unused import.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - mvn clean checkstyle:check (74/74 modules passed)
- Behavior changed: No
- Does this need documentation: No
@CalvinKirs

Copy link
Copy Markdown
Member Author

/run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-H: Total hot run time: 16874 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit c6c5996efa831c50143bdd9c2bf8f1a3ffd35247, data reload: false

------ Round 1 ----------------------------------
============================================
q1	17627	3070	3052	3052
q2	2143	253	224	224
q3	10193	852	519	519
q4	4670	249	199	199
q5	7680	551	395	395
q6	137	117	94	94
q7	526	531	389	389
q8	9241	952	920	920
q9	3441	2346	2368	2346
q10	6511	861	715	715
q11	394	199	180	180
q12	607	258	191	191
q13	18145	1507	1146	1146
q14	155	150	137	137
q15	q16	428	390	364	364
q17	1363	870	788	788
q18	3073	2209	2257	2209
q19	1256	865	801	801
q20	383	284	200	200
q21	5624	1774	1940	1774
q22	324	268	231	231
Total cold run time: 93921 ms
Total hot run time: 16874 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	3432	3385	3334	3334
q2	522	400	368	368
q3	2187	2271	2104	2104
q4	1180	1154	902	902
q5	2120	2085	2087	2085
q6	168	119	87	87
q7	1024	929	869	869
q8	1604	1411	1419	1411
q9	3125	3070	3070	3070
q10	1856	1771	1605	1605
q11	365	266	253	253
q12	450	429	346	346
q13	1478	1524	1139	1139
q14	172	178	154	154
q15	q16	391	397	354	354
q17	3522	3236	3142	3142
q18	4755	4414	4692	4414
q19	849	799	900	799
q20	990	958	834	834
q21	3843	3098	3320	3098
q22	399	346	318	318
Total cold run time: 34432 ms
Total hot run time: 30686 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 81557 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit c6c5996efa831c50143bdd9c2bf8f1a3ffd35247, data reload: false

query5	4264	405	318	318
query6	390	141	123	123
query7	4978	429	230	230
query8	291	120	114	114
query9	8686	2882	2876	2876
query10	420	219	185	185
query11	5381	1018	945	945
query12	118	68	67	67
query13	1191	496	317	317
query14	6121	2187	2064	2064
query14_1	1957	1940	1921	1921
query15	176	117	111	111
query16	923	373	352	352
query17	794	471	359	359
query18	2341	332	237	237
query19	168	137	108	108
query20	70	71	69	69
query21	209	100	88	88
query22	5331	5527	5337	5337
query23	6622	6243	6053	6053
query23_1	6214	5994	6176	5994
query24	7333	1112	753	753
query24_1	771	774	797	774
query25	411	277	230	230
query26	1216	218	122	122
query27	2808	416	249	249
query28	4701	1501	1489	1489
query29	920	420	328	328
query30	248	156	129	129
query31	816	393	320	320
query32	126	69	79	69
query33	485	218	161	161
query34	994	835	477	477
query35	414	381	333	333
query36	564	558	521	521
query37	120	82	66	66
query38	986	843	805	805
query39	489	479	468	468
query39_1	457	439	458	439
query40	195	86	73	73
query41	56	50	52	50
query42	71	69	74	69
query43	242	238	213	213
query44	1007	545	547	545
query45	106	101	100	100
query46	802	810	532	532
query47	753	765	722	722
query48	313	307	227	227
query49	542	224	198	198
query50	758	251	194	194
query51	8096	8032	8036	8032
query52	66	65	57	57
query53	197	190	146	146
query54	213	165	159	159
query55	74	62	61	61
query56	258	169	184	169
query57	686	689	669	669
query58	218	187	166	166
query59	1218	1210	1115	1115
query60	245	190	179	179
query61	148	142	164	142
query62	367	215	183	183
query63	170	143	136	136
query64	2676	663	566	566
query65	1643	1643	1592	1592
query66	1873	277	220	220
query67	9672	9731	9621	9621
query68	3050	1240	692	692
query69	355	222	190	190
query70	687	608	617	608
query71	248	178	163	163
query72	2365	1730	1563	1563
query73	675	549	323	323
query74	1995	1206	1143	1143
query75	1179	1092	956	956
query76	2388	732	539	539
query77	262	256	212	212
query78	3833	3663	3108	3108
query79	2279	806	586	586
query80	1618	318	278	278
query81	498	151	129	129
query82	644	123	92	92
query83	281	208	193	193
query84	295	109	91	91
query85	795	359	287	287
query86	406	196	172	172
query87	1016	974	886	886
query88	2761	2109	2081	2081
query89	289	197	174	174
query90	1999	127	126	126
query91	130	117	97	97
query92	78	69	69	69
query93	1486	1058	695	695
query94	688	248	227	227
query95	514	328	222	222
query96	823	588	278	278
query97	1054	1026	1025	1025
query98	168	136	132	132
query99	424	357	312	312
Total cold run time: 177894 ms
Total hot run time: 81557 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
ClickBench: Total hot run time: 14.62 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit c6c5996efa831c50143bdd9c2bf8f1a3ffd35247, data reload: false

query1	0.01	0.01	0.00
query2	0.09	0.04	0.04
query3	0.25	0.11	0.11
query4	1.60	0.10	0.10
query5	0.18	0.16	0.15
query6	1.22	0.67	0.70
query7	0.04	0.00	0.00
query8	0.05	0.03	0.04
query9	0.28	0.22	0.21
query10	0.35	0.35	0.34
query11	0.17	0.12	0.12
query12	0.15	0.12	0.12
query13	0.31	0.30	0.31
query14	0.44	0.44	0.44
query15	0.36	0.36	0.33
query16	0.23	0.21	0.21
query17	0.71	0.71	0.67
query18	0.19	0.16	0.17
query19	1.16	1.17	1.14
query20	0.01	0.01	0.01
query21	15.46	0.17	0.11
query22	5.03	0.05	0.04
query23	16.21	0.24	0.10
query24	3.10	0.33	0.25
query25	0.10	0.05	0.04
query26	0.71	0.16	0.13
query27	0.05	0.05	0.04
query28	3.61	0.50	0.28
query29	12.45	3.13	2.58
query30	0.25	0.12	0.12
query31	2.75	0.37	0.17
query32	3.50	0.32	0.24
query33	1.33	1.43	1.42
query34	15.32	2.19	1.77
query35	1.76	1.72	1.68
query36	0.46	0.29	0.29
query37	0.06	0.03	0.04
query38	0.04	0.03	0.02
query39	0.03	0.02	0.02
query40	0.12	0.08	0.08
query41	0.08	0.03	0.02
query42	0.04	0.02	0.02
query43	0.03	0.03	0.02
Total cold run time: 90.29 s
Total hot run time: 14.62 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 56.84% (162/285) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 49.76% (209/420) 🎉
Increment coverage report
Complete coverage report

### What problem does this PR solve?

Issue Number: None

Related PR: apache#67186

Problem Summary: HMS partition requests with exact and omission-tolerant contracts share per-partition in-flight loads. An omission-tolerant waiter could inherit an exact owner missing-result failure, a second-cache-check handoff could expose a batch without a bulk-load handle and dereference null after invalidation, and owner/waiter callers could race while rewriting statistics on the same shared exception. Retry shared missing-result failures under the waiter contract, make handleless handoffs invalidation-safe, and give each waiter a caller-local exception with a stable transport-stat snapshot.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - CachingHmsClientTest: 35 tests passed, including three new concurrent request-contract, invalidation, and failure-statistics cases
    - FE Maven CheckStyle validation passed with zero violations for all selected modules
- Behavior changed: Yes. Coalesced HMS partition requests now preserve each caller contract and failure statistics under concurrency.
- Does this need documentation: No
@CalvinKirs

Copy link
Copy Markdown
Member Author

/run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-H: Total hot run time: 16547 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit 4c73968ce6fb9212f35f2350f30b234b2ed4be3c, data reload: false

------ Round 1 ----------------------------------
============================================
q1	17611	3081	3078	3078
q2	2177	256	224	224
q3	10190	878	510	510
q4	4674	247	209	209
q5	7679	581	388	388
q6	138	108	93	93
q7	522	500	381	381
q8	9231	915	863	863
q9	3419	2365	2361	2361
q10	6495	844	723	723
q11	398	201	177	177
q12	608	259	206	206
q13	18143	1551	1164	1164
q14	155	150	140	140
q15	q16	434	393	360	360
q17	1354	890	792	792
q18	3094	2227	2216	2216
q19	1274	881	638	638
q20	369	281	199	199
q21	5556	1602	1848	1602
q22	336	263	223	223
Total cold run time: 93857 ms
Total hot run time: 16547 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	3441	3356	3336	3336
q2	514	391	378	378
q3	2331	2282	2233	2233
q4	1177	1143	876	876
q5	2158	2135	2099	2099
q6	166	115	85	85
q7	1011	928	871	871
q8	1597	1411	1421	1411
q9	3142	3061	3067	3061
q10	1816	1790	1605	1605
q11	353	267	249	249
q12	448	424	352	352
q13	1470	1517	1156	1156
q14	172	170	164	164
q15	q16	392	396	354	354
q17	3569	3328	3205	3205
q18	4759	4451	4722	4451
q19	838	818	915	818
q20	993	961	843	843
q21	3903	3074	3372	3074
q22	391	349	323	323
Total cold run time: 34641 ms
Total hot run time: 30944 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 81853 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit 4c73968ce6fb9212f35f2350f30b234b2ed4be3c, data reload: false

query5	4255	402	342	342
query6	428	136	121	121
query7	4938	423	238	238
query8	307	122	124	122
query9	8693	2881	2872	2872
query10	392	212	178	178
query11	5388	1030	903	903
query12	121	74	68	68
query13	1190	450	321	321
query14	6137	2180	2071	2071
query14_1	1964	1974	1938	1938
query15	183	115	109	109
query16	929	388	359	359
query17	797	467	383	383
query18	2344	331	245	245
query19	243	143	112	112
query20	70	74	70	70
query21	217	102	89	89
query22	5462	5297	5437	5297
query23	6515	6170	6151	6151
query23_1	6107	6128	6011	6011
query24	7264	1109	785	785
query24_1	780	771	781	771
query25	446	299	265	265
query26	1236	231	128	128
query27	2786	406	260	260
query28	4673	1504	1504	1504
query29	953	453	362	362
query30	257	157	132	132
query31	830	399	330	330
query32	158	89	92	89
query33	479	229	190	190
query34	1003	845	495	495
query35	417	392	347	347
query36	558	571	530	530
query37	127	83	74	74
query38	1016	835	812	812
query39	509	494	460	460
query39_1	472	467	456	456
query40	206	90	79	79
query41	59	56	55	55
query42	74	74	73	73
query43	244	243	211	211
query44	1058	538	548	538
query45	105	104	96	96
query46	799	826	541	541
query47	725	763	705	705
query48	313	303	231	231
query49	536	248	181	181
query50	723	257	188	188
query51	8129	7961	8138	7961
query52	65	75	62	62
query53	200	194	146	146
query54	246	165	161	161
query55	85	61	63	61
query56	289	165	156	156
query57	708	674	649	649
query58	223	164	163	163
query59	1203	1223	1101	1101
query60	242	178	192	178
query61	114	140	116	116
query62	413	200	172	172
query63	176	141	145	141
query64	2706	724	575	575
query65	1565	1557	1620	1557
query66	1936	261	199	199
query67	10229	9774	9526	9526
query68	2758	1175	762	762
query69	353	218	191	191
query70	673	618	612	612
query71	279	175	164	164
query72	2390	1697	1605	1605
query73	665	572	325	325
query74	1564	1207	1122	1122
query75	1144	1097	942	942
query76	2304	724	548	548
query77	253	255	209	209
query78	4087	3606	3216	3216
query79	2862	820	609	609
query80	1599	325	282	282
query81	532	154	129	129
query82	1239	120	92	92
query83	285	205	194	194
query84	305	116	93	93
query85	879	360	311	311
query86	545	179	175	175
query87	993	962	878	878
query88	2913	2097	2123	2097
query89	297	198	171	171
query90	2013	124	126	124
query91	136	121	103	103
query92	105	72	71	71
query93	1818	1097	703	703
query94	729	274	210	210
query95	545	337	228	228
query96	847	587	268	268
query97	1064	1049	1000	1000
query98	175	134	135	134
query99	481	347	305	305
Total cold run time: 180257 ms
Total hot run time: 81853 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
ClickBench: Total hot run time: 14.56 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit 4c73968ce6fb9212f35f2350f30b234b2ed4be3c, data reload: false

query1	0.01	0.01	0.01
query2	0.08	0.04	0.03
query3	0.25	0.10	0.10
query4	1.61	0.10	0.10
query5	0.18	0.16	0.15
query6	1.22	0.68	0.66
query7	0.04	0.01	0.00
query8	0.05	0.03	0.02
query9	0.28	0.21	0.21
query10	0.35	0.35	0.34
query11	0.17	0.11	0.11
query12	0.15	0.12	0.12
query13	0.32	0.30	0.30
query14	0.43	0.45	0.45
query15	0.36	0.35	0.34
query16	0.22	0.22	0.22
query17	0.67	0.69	0.68
query18	0.18	0.17	0.17
query19	1.19	1.19	1.13
query20	0.02	0.01	0.02
query21	15.45	0.17	0.11
query22	5.06	0.04	0.04
query23	16.18	0.25	0.10
query24	3.15	0.34	0.27
query25	0.14	0.05	0.05
query26	0.75	0.16	0.11
query27	0.03	0.04	0.03
query28	3.58	0.54	0.29
query29	12.44	3.13	2.55
query30	0.25	0.11	0.13
query31	2.76	0.36	0.17
query32	3.50	0.31	0.22
query33	1.35	1.38	1.55
query34	15.41	2.19	1.77
query35	1.76	1.69	1.72
query36	0.47	0.29	0.29
query37	0.06	0.04	0.04
query38	0.05	0.03	0.03
query39	0.03	0.02	0.02
query40	0.12	0.08	0.08
query41	0.08	0.02	0.02
query42	0.03	0.02	0.02
query43	0.03	0.02	0.03
Total cold run time: 90.46 s
Total hot run time: 14.56 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 70.03% (208/297) 🎉
Increment coverage report
Complete coverage report

### What problem does this PR solve?

Issue Number: None

Related PR: apache#67186

Problem Summary: Remove unused builders, extension points, convenience APIs, duplicate validation, and generic snapshot resolvers from the HMS partition batch path. Keep the access, batch executor, and transport flow one-way; preserve exact and omission-tolerant request semantics without an exception-subtype protocol. Keep single-flight active when partition retention is disabled, while using the existing bulk-load generation fence so invalidation still forces waiters to retry.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - 183 connector-cache and HMS tests passed through the JUnit launcher.
    - Modified connector sources and tests passed javac and Checkstyle 10.23.0.
    - Full Maven tests were not run because this worktree lacks thirdparty/installed/bin/thrift and thirdparty/installed/bin/protoc.
- Behavior changed: Yes (disabled partition retention still coalesces concurrent loads and now preserves invalidation fencing without retaining values)
- Does this need documentation: No
### What problem does this PR solve?

Issue Number: None

Related PR: apache#67186

Problem Summary: A same-mode partition waiter whose keys only partially overlapped an in-flight owner inherited the owner's failure even when the failure concerned keys outside the waiter request. Retry failed shared loads unless the waiter semantics and complete claimed-key set exactly match the owner, preserving caller-local failure isolation without depending on an internal exception subtype.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - 184 connector-cache and HMS tests passed through the JUnit launcher.
    - Modified sources and tests passed javac, Checkstyle 10.23.0, and git diff --check.
    - Full Maven tests were not run because this worktree lacks thirdparty/installed/bin/thrift and thirdparty/installed/bin/protoc.
- Behavior changed: Yes (partially overlapping waiters retry owner failures outside their own request)
- Does this need documentation: No
@CalvinKirs

Copy link
Copy Markdown
Member Author

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed against PR head 4c73968. The full authoritative diff and all changed paths were rechecked, with separate cache/HMS, scan/profile, MTMV, and SPI/property sweeps. Two distinct correctness issues remain and are called out inline: batch scans can leak connector statement-scope leases, and the new HMS batch-size property has inconsistent whitespace normalization. Existing cache/HMS metrics, MTMV pin, and profile-finalizer concerns were deduplicated against live review threads. No additional user focus was provided. No builds or tests were run, per the review prompt.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed against PR head 4c73968. The full authoritative diff and all changed paths were rechecked, with separate cache/HMS, scan/profile, MTMV, and SPI/property sweeps. Two distinct correctness issues remain and are called out inline: batch scans can leak connector statement-scope leases, and the new HMS batch-size property has inconsistent whitespace normalization. Existing cache/HMS metrics, MTMV pin, and profile-finalizer concerns were deduplicated against live review threads. No additional user focus was provided. No builds or tests were run, per the review prompt.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed against PR head 4c73968. The full authoritative diff and all changed paths were rechecked, with separate cache/HMS, scan/profile, MTMV, and SPI/property sweeps. Two distinct correctness issues remain and are called out inline: batch scans can leak connector statement-scope leases, and the new HMS batch-size property has inconsistent whitespace normalization. Existing cache/HMS metrics, MTMV pin, and profile-finalizer concerns were deduplicated against live review threads. No additional user focus was provided. No builds or tests were run, per the review prompt.

int end = Math.min(begin + batchSize, allPartitions.size());
if (batchException.get() != null || splitAssignment.isStop()) {
break;
SubmittedTaskFinalizer profileFinalizer = new SubmittedTaskFinalizer(() -> {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Close the connector statement scope for batch scans. FileQueryScanNode enters this path through SplitAssignment.init() -> startSplit(), so it bypasses getSplits(), the only place that currently registers statementScope::closeAll. The session captured here can own Iceberg TableLease/TrackedTable resources, but Arrow Flight sets returnResultFromLocal=false and StatementContext.close() deliberately skips its fallback close, relying on the query-finish callback. Because this batch path never registers that callback, each deferred Flight batch query can leave its scope and leases open. Please factor the callback registration into a helper and invoke it before dispatch in both batch flavors, with a lifecycle test that verifies closure after coordinator unregister.

}
int parsed;
try {
parsed = Integer.parseInt(value);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Normalize the raw batch-size property before parsing. The catalog binder trims values before binding this field, but both HiveCatalogProperties.of and HudiCatalogProperties.of then pass the original map to this constructor, where Integer.parseInt(value) is called without trimming. A quoted SQL property such as hive.hms_partitions_batch_size_per_rpc = ' 5000 ' therefore binds successfully and then throws while creating/replaying the catalog. Please trim (or pass the typed field) and add Hive/Hudi whitespace tests.

### What problem does this PR solve?

Issue Number: None

Related PR: apache#67186

Problem Summary: Hive and Hudi catalog property binding accepts surrounding whitespace for integer values, but HmsClientConfig reparsed the raw partition batch size without trimming it. Normalize the value before parsing so both catalog paths preserve the established typed-property behavior.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - HiveCatalogPropertiesTest, HudiCatalogPropertiesTest, and HmsPartitionBatchExecutorTest
- Behavior changed: Yes (partition batch sizes with surrounding whitespace are accepted consistently)
- Does this need documentation: No
@CalvinKirs

Copy link
Copy Markdown
Member Author

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the complete authoritative 49-file diff and current inline history on head 62fd254. Requesting changes for two distinct current-head issues: a P1 MTMV snapshot-consistency defect and a P2 HMS single-flight outage-amplification defect.

Critical checkpoints:

  • Goal and proof: The PR largely implements batched Hive partition access, explicit exact/omission contracts, cache coordination, profile reporting, and MTMV bulk freshness. The changed tests exercise many success, fallback, validation, and concurrency cases, but do not prove the two interleavings reported inline. No tests or builds were run in this review because the authoritative review instructions prohibit them.
  • Scope and clarity: The implementation is broad but organized around reusable request/result/executor abstractions and connector integration points. The remaining defects are incomplete propagation across existing parallel paths, not unrelated scope.
  • Concurrency and thread safety: Per-key owner/waiter election, invalidation/currentness, waiter accounting, cache close, capacity eviction, and bulk-load lifetime were traced. MF-1 remains: shape-incompatible waiters retry request-independent terminal failures and Error, multiplying work during an outage. No deadlock or separate currentness defect survived review.
  • Lifecycle: Pooled/unpooled client destruction, primary-exception preservation, scan finalizers, provider reselection, and read-transaction ownership otherwise survived. The asynchronous statement-scope closure defect is already covered by current-head comment 3921057327 and is not duplicated here.
  • Configuration: The new catalog batch-size property has a stable default, trimmed positive-integer validation, and consistent Hive/Hudi construction. It is catalog-scoped rather than dynamically mutable; no separate replay/configuration issue survived.
  • Compatibility: Exact and omission-tolerant APIs preserve ordered scalar fallback for connectors. Existing connector-SPI version/surface concerns are already covered by comments 3868649356 and 3870178439. No FE-BE protocol or storage-format change is introduced.
  • Parallel paths and conditions: Exact versus omission callers, synchronous/batch/streaming scan modes, PCT versus non-PCT MTMV bases, SELF_MANAGE/mixed MVs, and local/cloud version paths were checked. MF-2 is the remaining missed parallel path: non-PCT table snapshots bypass the task pin.
  • Test coverage and results: Focused FE unit tests use deterministic coordination for the covered races, but coverage is missing for broad-owner/singleton-waiter global failure and non-PCT S1-to-S2 task persistence. Existing changed expectations were inspected; no result files were added.
  • Observability: Query-profile and batch-stat success/failure handoff is generally preserved. The reachable exact-waiter stats gap has no current production stats consumer and was dismissed with evidence; existing profile/metrics concerns were duplicate-fenced.
  • Persistence and data correctness: MF-2 can persist S2 freshness after refresh SQL read S1, allowing stale MV contents into rewrite. Other mapping/PCT pin and missing-result isolation paths now preserve their intended snapshot/error contracts. There is no new transaction, data-write, EditLog, or FE-BE variable-passing path to validate.
  • Performance: Batching removes the principal per-partition RPC pattern, but MF-1 can undo single-flight protection during global outages. No additional substantiated hot-path regression survived the full sweep.
  • Other issues and user focus: No additional review focus was specified. All other candidates were independently accepted, dismissed with code evidence, or fenced by existing threads; three Round 2 reviewers returned NO_NEW_VALUABLE_FINDINGS.

return context;
}

private Optional<MvccSnapshot> resolveSnapshot(MTMVRelatedTableIf table) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Apply the task pin to non-PCT table snapshots too. This resolver now keeps mapping and PCT partition snapshots at S1, but MTMVPartitionUtil.getTableSnapshotFromContext still calls MvccUtil.getSnapshotFromContext directly. During MTMVTask.run the outer context has no StatementContext, so an Iceberg/Paimon non-PCT base can materialize latest S2 here; each later refresh SQL explicitly scans the task pin S1, while generatePartitionSnapshots persists the cached S2. The MV can then be considered fresh at S2 and used for rewrite although S2 was never materialized. Reuse this context resolver for table-level snapshots and add a non-PCT S1-to-S2 task interleaving test.

try {
Throwable failure = batch.await();
if (failure != null) {
if (batch.allowMissing != allowMissing

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Share request-independent terminal failures with partial waiters. This compatibility check runs before the failure is classified, so a waiter covering a subset (or using the other missing-result contract) retries even pool/client-creation, authentication, connection failures, and Error. For one owner of N cold keys plus N singleton waiters, a global owner failure releases every waiter into a separate delegate attempt under the same outage, defeating single-flight and potentially saturating the metadata pool. Only result-integrity failures can depend on identities outside a waiter's request; propagate request-independent failures and Error to all overlapping waiters, and add a broad-owner/singleton-waiters outage test.

### What problem does this PR solve?

Issue Number: None

Related PR: apache#67186

Problem Summary: Partial single-flight waiters retried request-independent HMS failures, amplifying metadata outages, while MTMV non-PCT table snapshots bypassed the refresh task's pinned MVCC snapshot. Share terminal HMS failures with all overlapping waiters while retaining retries for request-dependent result-integrity failures, and route non-PCT table snapshot reads through the refresh context's pin resolver.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - CachingHmsClientTest and MTMVRefreshContextBatchTest
- Behavior changed: Yes (overlapping HMS failures remain single-flight and MTMV refresh snapshots remain task-pinned)
- Does this need documentation: No
@CalvinKirs

Copy link
Copy Markdown
Member Author

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the full authoritative PR diff and the required connector/FE guidance. The cache, batching/transport, profile publication, Hive/Hudi integration, and MTMV snapshot paths were checked with three independent risk sweeps. One distinct P2 lifecycle issue is raised inline below. The SPI-major, MVCC mapping/type, vanished-partition, profile-finalization, and request-failure concerns were hard-deduplicated against existing review threads. No builds or tests were run because the review bundle forbids them.

return execute(client -> {
List<Partition> partitions =
client.getPartitionsByNames(dbName, tableName, partNames);
return partitions.stream()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Preserve the closed-client guard for empty partition requests. getPartitionsWithStats and getExistingPartitionsWithStats build the request before any closed check, while HmsPartitionBatchExecutor returns immediately for an empty request (lines 57-65), so after ThriftHmsClient.close() an empty getPartitions/getExistingPartitions call silently succeeds. The old getPartitions path entered execute, which rejected closed clients up front; this now lets a close/query race look like a valid empty scan. Check closed at the start of both public batch methods (and add pooled/unpooled post-close empty-request coverage) to preserve the client lifecycle contract.

@924060929 924060929 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed current head 0478f0c35cf7be5a45e8878a0cd06dc15f56a0c9.

The core layering is now much clearer: one logical HmsClient request flows through a bounded batch executor to a leaf HMS transport, with response validation and request-order reconstruction centralized in the executor. The MTMV integration is also now engine-agnostic through the default bulk MTMVRelatedTableIf#getPartitionSnapshots adapter.

Three current issues still need to be addressed before approval:

  1. The batch/streaming startSplit paths still bypass the query-finish registration used by getSplits, so the connector statement scope can remain open for deferred/Arrow Flight scans. This is the remaining P1 lifecycle issue.
  2. A successful pruning HMS request can still disappear from Query Profile when later Nereids pruning reduces the selection to zero, because the stats remain on the handle and planScan never consumes them.
  3. Empty partition requests on a closed ThriftHmsClient still return successfully because the executor short-circuits before the closed-client guard.

Several older unresolved threads are already fixed in the current code: selective nonempty pruning now carries stats on the handle, whole-table freshness uses omission-tolerant access, per-partition MTMV rewrite failures are deferred and isolated, and failed pruning stats are collected through statement scope. The removed fallback-timeout thread is also obsolete.

The PR is still broader than its stated scope: CachingHmsClient implements a substantial per-partition single-flight owner/waiter protocol and extends generic MetaCache currentness behavior even though the PR description says cache single-flight is out of scope. This should either be split into a separately justified change or described and validated as part of this PR.

Finally, the PR currently conflicts with master in MTMV, MTMVTask, and an MTMV rewrite test. This is not a mechanical rebase because master has substantially refactored MTMV around IVM refresh/fallback flows; the preload and pinned-snapshot placement needs another lifecycle review after resolving those conflicts.

Recommendation: keep CHANGES_REQUESTED until the P1/P2 items are fixed and the rebased MTMV flow is re-reviewed. The request-shape evidence is useful, but the current head still has no real 120k-partition end-to-end performance result.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants